home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / gems / gemsiii.lha / gemsIII / luminaire / sphere_luminaire.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-20  |  1.6 KB  |  53 lines

  1. // ******************************************************************
  2. //
  3. // Physically Correct Direct Lighting For Distribution Ray Tracing
  4. //             by Changyaw Wang
  5. //
  6. // sphere_luminaire.c
  7. //
  8. // ******************************************************************
  9.  
  10. #include "utility.h"
  11.  
  12. // Selects a point visible from x given (r1,r2).  
  13. // Here, visible means not SELF-shadowed.
  14.  
  15. void sphere::select_visible_point(
  16.              const point& x,   // viewpoint
  17.              const double r1,  // random number
  18.              const double r2,  // random number
  19.              point& on_light,  // point corresponding to (r1,r2)
  20.              double& prob)     // probability of selecting on_light
  21. {
  22.    rotation_matrix m;
  23.    double theta, phi, theta_max;
  24.    vector v1, v2, u, v, w, t, psi;
  25.  
  26.    theta_max = asin(radius/distance(x,center));
  27.    theta = acos(1.0 - r1 + r1 * cos(theta_max)); 
  28.    phi   = 2.0 * PI * r2;
  29.    psi  = spherical_to_vector(theta,phi);
  30.    w = center - x;             // (u,v,w) is (X',Y',Z') in the text
  31.    w.normalize();
  32.    if(fabs(w.data[0]) >= fabs(w.data[1]))
  33.       { t.data[0] = 0.0; t.data[1] = 1.0; t.data[2] = 0.0; } 
  34.    else
  35.       { t.data[0] = 1.0; t.data[1] = 0.0; t.data[2] = 0.0; }
  36.    u = cross(w,t);
  37.    u.normalize();
  38.    v = cross(w,u);
  39.    v.normalize();
  40.    m.set_identity();
  41.    m.set_xyz_to_uvw(u,v,w);
  42.    psi = m * psi;
  43.    psi.normalize();
  44.    hit(x, psi, on_light);       // on_light is x" in the text
  45.    v1 = on_light - center;
  46.    v1.normalize();
  47.    v2 = x - on_light;
  48.    v2.normalize();
  49.    prob = dot(v1,v2) * 0.5 / 
  50.        (distance_squared(x,on_light) * PI * (1.0 - cos(theta_max))); 
  51. }
  52.  
  53.